package com.koron.common.core.feignConfig;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.koron.bean.system.staff.Constant;
import com.koron.common.core.config.ThreadLocalContext;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Collection;
import java.util.Map;
import java.util.Objects;


/**
 * Feign配置
 * 使用FeignClient进行服务间调用，传递headers信息
 */
@Slf4j
@Configuration
public class FeignConfig implements RequestInterceptor {

    @Override
    public void apply(RequestTemplate requestTemplate) {
        /*
        开启了 Hystrix  Hystrix的默认隔离策略是THREAD 。而 RequestContextHolder 源码中，使用了两个ThreadLocal
        两种方式:
        1.配置隔离级别 (Hystrix官方强烈建议使用THREAD作为隔离策略)
        2.自定义并发策略  继承HystrixConcurrencyStrategy ，并重写wrapCallable 方法
        */
        String token = "";
        String currDs = "";
        String currOrg = "";
        String currLeader = "";
        String currLeaderOrg = "";
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();

        if (Objects.isNull(attributes) || Objects.isNull(attributes.getRequest())) {
            //请求为空
            currDs = ThreadLocalContext.get().getCurrDs();
            currOrg = ThreadLocalContext.get().getCurrOrg();
            currLeader = ThreadLocalContext.get().getCurrLeader();
            currLeaderOrg = ThreadLocalContext.get().getCurrLeaderOrg();
            log.info("feign-ThreadLocalContext发起调用传递请求头参数 currDs:{},currOrg:{},currLeader:{},currLeaderOrg:{}",currDs,currOrg,currLeader,currLeaderOrg);
        } else {
            HttpServletRequest request = attributes.getRequest();
            String currDs_tmp = (String) request.getAttribute(Constant.DYNAMIC_DATA_SOURCE);
            token = request.getHeader(Constant.JWT_TOKEN);
            currDs = StringUtils.isEmpty(currDs_tmp)?request.getHeader(Constant.DYNAMIC_DATA_SOURCE):currDs_tmp;
            currOrg = request.getHeader(Constant.DYNAMIC_AGENT_ORG);
            currLeader = request.getHeader(Constant.DYNAMIC_LEADER);
            currLeaderOrg = request.getHeader(Constant.DYNAMIC_LEADER_ORG);
            log.info("feign-request发起调用传递请求头参数 currDs:{},currOrg:{},currLeader:{},currLeaderOrg:{}",currDs,currOrg,currLeader,currLeaderOrg);
        }
        Map<String, Collection<String>> headers = requestTemplate.headers();
        String currDsHeaders = null;
        if (CollectionUtil.isNotEmpty(headers)){
            Collection<String> ds = headers.get("currDs");
            if (CollectionUtil.isNotEmpty(ds)){
                currDsHeaders = ds.stream().findFirst().get();
                log.info("feign-request发起调用传递请求头参数 currDsHeaders:{}", currDsHeaders);
            }
        }
        //添加token
        requestTemplate.header(Constant.JWT_TOKEN, token);
        requestTemplate.header(Constant.DYNAMIC_DATA_SOURCE, !StrUtil.isBlank(currDsHeaders) ? currDsHeaders :  currDs);
        requestTemplate.header(Constant.DYNAMIC_AGENT_ORG, currOrg);
        requestTemplate.header(Constant.DYNAMIC_LEADER, currLeader);
        requestTemplate.header(Constant.DYNAMIC_LEADER_ORG, currLeaderOrg);
        log.info("requestTemplate:headers:{}", JSONUtil.toJsonStr(requestTemplate.headers()));
        ThreadLocalContext.clear();
    }

}
